import random as disturb
from typing import Any

import numpy as np


def get_estimated_value(precision, func, diff_func, X, x) -> float:
    next_x = x - func.subs(X, x) / diff_func.subs(X, x)

    while abs(next_x - x) >= precision:
        x0 = next_x
        next_x = x0 - func.subs(X, x) / diff_func.subs(X, x)
    return next_x


def get_disturbance_factor(reduction, magnification) -> float:
    return disturb.uniform(reduction, magnification)


def get_window_matrix(seqment, length) -> Any:
    t_matrix = []

    for item in seqment:
        st = seqment.index(item)
        if st >= len(seqment) - length:
            break

        row = []
        for i in range(st, st + length):
            row.append(seqment[i])

        t_matrix.append(row)

    return np.array(t_matrix).T


def normalize(data, max_val, min_val):
    return [(data[i] - min_val) / (max_val - min_val) for i in range(len(data))]


def anti_normalize(data, max_val, min_val):
    return [data[i] * (max_val - min_val) + min_val for i in range(len(data))]
